#include "string/string_util.h"
#include "string/string.h"

#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <stdio.h>

static String vfmt(const char* str, int str_len, va_list args)
{
	String result;
	result.length(str_len * 2);

	while (true)
	{
		int written = vsnprintf(
			result.data(),
			result.length(),
			str,
			args);

		// Not enough space in string?
		// Try again.
		if (written < 0)
		{
			result.length(result.length() * 2);
			continue;
		}
		else
		{
			result.length(written);
			break;
		}
	}

	return result;
}

String fmt(const char* str, ...)
{
	va_list args;
	va_start(args, str);
	String result = vfmt(str, (int) std::strlen(str), args);
	va_end(args);

	return result;
}

// Guess why fmt(const String& str) doesn't work?
// Because va_start doesn't like references. Teh suck.
String fmt(String str, ...)
{
	va_list args;
	va_start(args, str);
	String result = vfmt(str.c_str(), str.length(), args);
	va_end(args);

	return result;
}
